package com.chenfan.mcn.controller;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.common.annotations.DataPrivilege;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.clients.baseinfo.BaseInfoClient;
import com.chenfan.mcn.clients.baseinfo.CustomerAccountOrBillingInfoResp;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.mcn.model.McnPage;
import com.chenfan.mcn.model.StarBasicData;
import com.chenfan.mcn.model.YearFrameContract;
import com.chenfan.mcn.model.YearSupplementaryAgreement;
import com.chenfan.mcn.model.dto.YearFrameContractSearchDTO;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.service.StarBasicDataService;
import com.chenfan.mcn.service.YearFrameContractService;
import com.chenfan.mcn.service.YearSupplementaryAgreementService;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.privilege.common.config.SearchAuthority;
import com.chenfan.privilege.common.config.UrlAuth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 年框合同
 * @Author liuyang
 * @Date 2021/1/19
 * @Time 17:36
 * @Version V1.0
 **/
@Slf4j
@RestController
@RequestMapping("/year/frame")
public class YearFrameContactController {

    @Autowired
    private YearFrameContractService yearFrameContractService;

    @Autowired
    private YearSupplementaryAgreementService yearSupplementaryAgreementService;

    @Autowired
    private BaseInfoClient baseInfoClient;

    @Autowired
    private StarBasicDataService starBasicDataService;


    /**
     * 新增/编辑年框合同
     *
     * @param yearFrameContractVO 请求参数
     * @return 请求参数
     */
    @PostMapping(value = "/save", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"yearContract_addy","yearContract_edit"})
    public Res<Long> save(@RequestBody YearFrameContractVO yearFrameContractVO) {
        Assert.notNull(yearFrameContractVO.getTargetType(), "未标记签约对象");
        Assert.notNull(NumberCst.ONE.equals(yearFrameContractVO.getTargetType()) || NumberCst.TWO.equals(yearFrameContractVO.getTargetType()), "请正确标记签约对象！【1-客户、2-红人】");
        return Res.ok(yearFrameContractService.saveData(yearFrameContractVO));
    }


    /**
     * 根据客户获取折扣审批单
     *
     * @param customerId {@link String}
     * @return {@link DiscountApprovalVO}
     */
    @GetMapping(value = "/getDiscountApproval", produces = {"application/json;charset=UTF-8"})
    public Res<DiscountApprovalVO> getDiscountApprovalData(Long customerId) {
        List<DiscountApprovalVO> voList = yearFrameContractService.getDiscountApproval(customerId, false);
        BusinessAssert.notEmpty(voList, McnErrorCode.NO_VALID_DISCOUNT);
        return Res.ok(voList.get(0));
    }

    /**
     * 根据客户ID获取可选择的的折扣审批单【下拉框】
     *
     * @param customerId {@link String}
     * @return {@link DiscountApprovalVO}
     */
    @GetMapping(value = "/getOptionalDiscountApproval", produces = {"application/json;charset=UTF-8"})
    public Res<List<DiscountApprovalVO>> getOptionalDiscountApproval(Long customerId) {
        return Res.ok(yearFrameContractService.getDiscountApproval(customerId, true));
    }

    /**
     * 新增/编辑年框合同补充协议
     *
     * @param yearSupplementaryAgreementVO 请求参数
     * @return 请求参数
     */
    @PostMapping(value = "/addAgreement", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"yearContract_addb"})
    public Res<Object> addSupplementaryAgreement(@RequestBody YearSupplementaryAgreementVO yearSupplementaryAgreementVO) {
        JSONArray jsonObject = JSONArray.parseArray(yearSupplementaryAgreementVO.getMainChanges());
        for (Object obj : jsonObject) {
            if (Integer.parseInt(obj.toString()) == NumberCst.ONE) {
                boolean existed = Objects.nonNull(yearSupplementaryAgreementVO.getContactSubjectBeforeChange())
                        && Objects.nonNull(yearSupplementaryAgreementVO.getContactSubjectAfterChange());
                if (existed) {
                    if (yearSupplementaryAgreementVO.getContactSubjectAfterChange()
                            .equals(yearSupplementaryAgreementVO.getContactSubjectBeforeChange())) {
                        throw new BusinessException(McnErrorCode.CONTENT_SAME);
                    }
                }
            }
            if (Integer.parseInt(obj.toString()) == NumberCst.TWO) {
                boolean existed = Objects.nonNull(yearSupplementaryAgreementVO.getDiscountApprovalAfterChange())
                        && Objects.nonNull(yearSupplementaryAgreementVO.getDiscountApprovalBeforeChange());
                if (existed) {
                    if (yearSupplementaryAgreementVO.getDiscountApprovalAfterChange()
                            .equals(yearSupplementaryAgreementVO.getDiscountApprovalBeforeChange())) {
                        throw new BusinessException(McnErrorCode.CONTENT_SAME);
                    }
                }
            }
        }
        try {
            yearFrameContractService.addSupplementaryAgreement(yearSupplementaryAgreementVO);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Res.failed(McnErrorCode.DATA_INSERT_ERROR, e.getMessage());
        }
        return Res.ok();
    }


    /**
     * 修改年框合同状态
     *
     * @param yearFrameContract {@link YearFrameContract}
     * @return {@link Res}
     */
    @PostMapping(value = "/status/change")
    @UrlAuth({"yearContract_revocation","yearContract_cancellation","yearContract_submit"})
    public Res<Object> changeStatus(@RequestBody YearFrameContract yearFrameContract) {
        if (Objects.isNull(yearFrameContract.getId()) || Objects.isNull(yearFrameContract.getYearStatus())) {
            throw new BusinessException(McnErrorCode.PARAM_ERROR);
        }
        return yearFrameContractService.changeStatus(yearFrameContract) ? Res.ok() : Res.failed();
    }


    /**
     * 修改年框合同补充协议状态
     *
     * @param yearSupplementaryAgreement {@link YearSupplementaryAgreement}
     * @return {@link Res}
     */
    @PostMapping(value = "/supplement/status")
    @UrlAuth({"yearContract_b_revocation","yearContract_b_cancellation","yearContract_b_submit"})
    public Res<Object> changeSupplementStatus(@RequestBody YearSupplementaryAgreement yearSupplementaryAgreement) {
        if (Objects.isNull(yearSupplementaryAgreement.getId()) || Objects.isNull(yearSupplementaryAgreement.getStatus())) {
            throw new BusinessException(McnErrorCode.PARAM_ERROR);
        }
        return yearSupplementaryAgreementService.changeSupplementStatus(yearSupplementaryAgreement) ? Res.ok() : Res.failed();
    }


    /**
     * 详情
     *
     * @param yearId {@link Long}
     * @return {@link YearFrameContractVO}
     */
    @GetMapping(value = "/info", produces = {"application/json;charset=UTF-8"})
    public Res<YearFrameContractVO> info(Long yearId) {
        return Res.ok(yearFrameContractService.info(yearId));
    }


    /**
     * 年框合同分页数据
     *
     * @return {@link YearFrameVO}
     */
    @GetMapping(value = "/getList", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"yearContract_search"})
    public Res<Page<YearFrameVO>> getList(@ApiIgnore McnPage<YearFrameVO> page, @SearchAuthority YearFrameContractSearchDTO yearFrameContractSearchDTO) {
        return Res.ok(yearFrameContractService.getList(page, yearFrameContractSearchDTO));
    }

    /**
     * 年框合同列表导出
     *
     * @param yearFrameContractSearchDTO {@link YearFrameContractSearchDTO}
     * @return {@link Res}
     */
    @GetMapping(value = "/exportExcel")
    @UrlAuth({"yearContract_export"})
    public Res<Object> exportExcel(@SearchAuthority YearFrameContractSearchDTO yearFrameContractSearchDTO, @ApiIgnore HttpServletResponse response) {
        try {
            yearFrameContractService.exportExcel(yearFrameContractSearchDTO, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Res.failed(McnErrorCode.FAILED);
        }
        return Res.ok();
    }

    /**
     * 获取所有的年框合同
     *
     * @param yearFrameContractSearchDTO {@link YearFrameContractSearchDTO}
     * @return {@link List<String>}
     */
    @DataPrivilege(pageComponent = "yearContract")
    @GetMapping(value = "/getYearCode")
    public Res<List<YearFrameContractVO>> getYearCode(@SearchAuthority YearFrameContractSearchDTO yearFrameContractSearchDTO) {
        return Res.ok(yearFrameContractService.getYearCode(yearFrameContractSearchDTO));
    }


    /**
     * 自动带出变更前后折扣返点审批单数据
     *
     * @param yearCode {@link String}
     * @return {@link ChangeDiscountApproval}
     */
    @GetMapping(value = "/getChangeDiscountApproval")
    public Res<ChangeDiscountApproval> getChangeDiscountApproval(String yearCode) {
        if (Objects.isNull(yearCode)) {
            throw new BusinessException(McnErrorCode.PARAM_ERROR);
        }
        return Res.ok(yearFrameContractService.getChangeDiscountApproval(yearCode));
    }

    /**
     *
     * @param mcnPage
     * @param customerId
     * @return
     */
    @GetMapping("/cusYearContract")
    public Res<Page<CusYearContractVO>> getCusYearContract(@ApiIgnore McnPage<CusYearContractVO> mcnPage, @RequestParam Long customerId) {
        return Res.ok(yearFrameContractService.getCusYearContract(mcnPage, customerId));
    }


    /**
     * 客户下所有年框合同
     *
     * @param customerId 客户id
     * @return 年框合同列表
     */
    @GetMapping("/getYearContractByCustomerId")
    public Res<List<YearFrameContractVO>> getYearContractByCustomerId(Long customerId) {
        return Res.ok(yearFrameContractService.getYearContractByCustomerId(customerId));
    }

    /**
     * 获取所有MCN客户&红人列表
     * @return
     */
    @GetMapping("/getAllCustomerOrStar")
    public Res<List<CustomerOrStarVO>> getAllCustomerOrStar() {
        List<CustomerAccountOrBillingInfoResp> accountOrBillingInfoResps = baseInfoClient.allAccountInfo().getObj();
        List<CustomerOrStarVO> dataList = CommonUtil.defaultList(accountOrBillingInfoResps).stream()
                .filter(x -> "10".equals(x.getCustomerType())).map(e -> {
            CustomerOrStarVO  customerOrStarVO = new CustomerOrStarVO();
            customerOrStarVO.setCustomerId(e.getCustomerId());
            customerOrStarVO.setCustomerName("【客户】" + e.getCustomerNameC());
            customerOrStarVO.setTargetType(NumberCst.ONE);
            return customerOrStarVO;
        }).collect(Collectors.toList());
        List<StarBasicData> starList = starBasicDataService.selectList(Wrappers.lambdaQuery(StarBasicData.class)
            .eq(StarBasicData::getIsDelete, NumberCst.ZERO)
            .eq(StarBasicData::getStarStatus, NumberCst.ZERO)
        );
        dataList.addAll(CommonUtil.defaultList(starList).stream().map(e -> {
            CustomerOrStarVO  customerOrStarVO = new CustomerOrStarVO();
            customerOrStarVO.setCustomerId(e.getId());
            customerOrStarVO.setCustomerName("【红人】" + e.getStarNickname());
            customerOrStarVO.setTargetType(NumberCst.TWO);
            return customerOrStarVO;
        }).collect(Collectors.toList()));
        return Res.ok(dataList);
    }
}
